<template>
  <div>
    <el-form ref="spuForm" label-width="100px" :model="spuInfo" :rules="spuRules">
      <el-form-item prop="spuName" label="SPU 名称">
        <el-input v-model="spuInfo.spuName" placeholder="SPU 名称"></el-input>
      </el-form-item>
      <el-form-item prop="tmId" label="品牌">
        <el-select v-model="spuInfo.tmId">
          <el-option v-for="tm in baseTrademarkList" :key="tm.id" :value="tm.id" :label="tm.tmName"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="description" label="SPU描述">
        <el-input v-model="spuInfo.description" type="textarea" rows="4" placeholder="SPU描述"></el-input>
      </el-form-item>
      <el-form-item prop="spuImageList" label="SPU图片">
        <el-upload v-model:file-list="fileList" :action="`${BASE_URL}/admin/product/upload`" list-type="picture-card"
          :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleSuccess"
          :before-upload="handleBeforeUpload">
          <el-icon>
            <Plus />
          </el-icon>
        </el-upload>
      </el-form-item>
      <el-form-item prop="spuSaleAttrList" label="销售属性">
        <el-select :disabled="saleAttrSelectDisabled" v-model="spuSaleAttr"
          :placeholder="`还有${filterSaleAttr.length}项未选择`">
          <el-option v-for="saleAttr in filterSaleAttr" :key="saleAttr.id" :value="saleAttr.id + ':' + saleAttr.name"
            :label="saleAttr.name"></el-option>
        </el-select>
        <el-button @click="handleAddSaleAttr" :disabled="!spuSaleAttr" type="primary" :icon="Plus"
          style="margin-left: 10px">添加销售属性</el-button>
        <el-table :data="spuInfo.spuSaleAttrList || []" border style="margin-top: 15px">
          <el-table-column v-slot="{ $index }" label="序号" width="80">
            {{ $index + 1 }}
          </el-table-column>
          <el-table-column prop="saleAttrName" label="属性名" width="100"></el-table-column>
          <el-table-column v-slot="{ row }" label="属性值名称列表">
            <el-tag v-for="(spuSaleAttrValue, index) in row.spuSaleAttrValueList || []"
              :key="spuSaleAttrValue.saleAttrValueName" class="mx-1" closable :disable-transitions="false"
              @close="handleClose(row, index)" style="margin-left: 5px">
              {{ spuSaleAttrValue.saleAttrValueName }}
            </el-tag>
            <el-input v-if="row.inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20" size="small"
              @keyup.enter="handleInputConfirm(row)" @blur="handleInputConfirm(row)" style="width:80px" />
            <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput(row)" :icon="Plus"
              style="margin-left: 5px"></el-button>
          </el-table-column>
          <el-table-column v-slot="{ $index }" label="操作" width="100">
            <el-button @click="handleDeleteSaleAttr($index)" type="danger" :icon="Delete" size="small"></el-button>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item>
        <el-button @click="handleSaveSpuInfo(spuForm)" type="primary" v-if="!spuInfo.id">保存</el-button>
        <el-button @click="handleUpdateSpuInfo(spuForm)" type="primary" v-else>保存</el-button>
        <el-button @click="handleCancelSpuInfo">取消</el-button>
      </el-form-item>
    </el-form>
    <!-- 图片预览窗口 -->
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>
<script lang="ts">
export default {
  name: 'SpuForm',
}
</script>

<script setup lang="ts">
import { onMounted, ref, reactive, computed, nextTick } from 'vue'
import { Plus, Delete } from '@element-plus/icons-vue'
import type { UploadProps, UploadUserFile, ElInput, FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import type { spuItemModel, spuSaleAttrListModel, spuTrademarkListModel, spuBaseSaleAttrListModel, spuSaleAttrModel } from '@/api/product/model/spu'
import { reqGetBaseSaleAttrList, reqGetBaseTrademarkList, reqGetSpuImageList, reqGetSpuSaleAttrList, reqSaveSpuInfo, reqUpdateSpuInfo } from '@/api/product/spu'
import { useCategoryStore } from '@/stores/category'
const spuForm = ref<FormInstance>()
const baseTrademarkList = ref<spuTrademarkListModel>([]) // 销售品牌
const baseSaleAttrList = ref<spuBaseSaleAttrListModel>([]) // 基本销售属性
const BASE_URL = import.meta.env.VITE_API_URL // 上传的baseUrl
const fileList = ref<UploadUserFile[]>([])
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
// 移除图片
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  spuInfo.spuImageList = spuInfo.spuImageList.filter(item => item.imgUrl != uploadFile.url)
}
// 预览图片
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}
// 上传之前：校验文件类型、大小等信息
const handleBeforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
  // console.log('上传前', rawFile)
  // 上传前：校验文件类型、大小等信息
}
// 上传成功后：收集返回的在线url
const handleSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {
  // 收集数据到 spuInfo 中的 spuImageList 中
  spuInfo.spuImageList.push({
    imgName: uploadFile.name,
    imgUrl: response.data as string
  })
}

// 获取基本数据
const getBaseData = async () => {
  baseSaleAttrList.value = await reqGetBaseSaleAttrList()
  baseTrademarkList.value = await reqGetBaseTrademarkList()
}
// 挂载完成后获取基本数据 
onMounted(() => {
  // 挂载完成后获取基本数据 
  getBaseData()
})

// 收集数据 数据结构
const spuSaleAttr = ref('')
const spuInfo = reactive<spuItemModel>({
  spuName: '',
  description: '',
  category3Id: 0,
  tmId: undefined, // 品牌id
  spuSaleAttrList: [], // 销售属性名列表
  spuImageList: [] // 图片列表
})

// 添加销售属性
const handleAddSaleAttr = () => {
  const [baseSaleAttrId, saleAttrName] = spuSaleAttr.value.split(':')
  spuInfo.spuSaleAttrList.push({
    baseSaleAttrId: parseInt(baseSaleAttrId),
    saleAttrName,
    spuSaleAttrValueList: [],
    inputVisible: false
  })
  // 清空 销售属性展示框
  spuSaleAttr.value = ''
}
// 删除销售属性
const handleDeleteSaleAttr = (index: number) => {
  spuInfo.spuSaleAttrList.splice(index, 1)
}
// 过滤后的 saleAttrList：添加到表格后的数据要删除掉
const filterSaleAttr = computed(() => {
  return baseSaleAttrList.value.filter(item => !spuInfo.spuSaleAttrList?.find(item2 => item.id == item2.baseSaleAttrId))
})

/**
 * 动态属性值 tag
 */
const inputValue = ref('')
const InputRef = ref<InstanceType<typeof ElInput>>()
// 删除某个saleAttr的 tag
const handleClose = (row: spuSaleAttrModel, index: number) => {
  row.spuSaleAttrValueList.splice(index, 1)
}
// 显示属性值输入框并聚焦到输入框
const showInput = (row: spuSaleAttrModel) => {
  row.inputVisible = true
  nextTick(() => {
    InputRef.value!.input!.focus()
  })
}
// 添加属性值
const handleInputConfirm = (row: spuSaleAttrModel) => {
  // 属性值不为空
  if (inputValue.value) {
    // 不能重复添加重复的属性
    if (row.spuSaleAttrValueList.find(item => item.saleAttrValueName == inputValue.value)) {
      ElMessage.info('属性值不能重复！')
    } else {
      row.spuSaleAttrValueList.push({
        baseSaleAttrId: row.baseSaleAttrId,
        saleAttrValueName: inputValue.value
      })
    }
  }
  row.inputVisible = false
  inputValue.value = ''
}

// 保存(添加) spu 信息
const categoryStore = useCategoryStore()
const handleSaveSpuInfo = async (spuForm: FormInstance) => {
  spuForm.validate(async (valid, fields) => {
    // 验证通过
    if (valid) {
      // 处理数据：删除没有属性值的属性对象，删除 inputVisible
      spuInfo.spuSaleAttrList = spuInfo.spuSaleAttrList.filter(item => {
        if (item.spuSaleAttrValueList.length > 0) {
          delete item.inputVisible
          return true
        }
        return false
      })

      // 如果属性值列表为空，则不发请求
      if (spuInfo.spuSaleAttrList.length == 0) {
        ElMessage.warning('SPU销售属性为必填项')
        return
      }

      // 添加 spu 之前，把 category3Id 添加上
      spuInfo.category3Id = categoryStore.cate3Id as number

      // 发送保存spuInfo请求
      await reqSaveSpuInfo(spuInfo)
      ElMessage.success('添加成功！')
      // 切换Tab 至 SpuList
      emit('changeTab', 1)
    }
  })
}
// 取消添加 spu 信息
const emit = defineEmits(['changeTab'])
const handleCancelSpuInfo = () => {
  // 切换到spuList
  emit('changeTab', 1)
}

// 销售属性选择框是否禁用
const saleAttrSelectDisabled = computed(() => {
  if (spuInfo.spuSaleAttrList?.length > 0 && !spuInfo?.spuSaleAttrList.slice(-1)[0]?.spuSaleAttrValueList[0]?.saleAttrValueName) {
    return true
  }
  return false
})

/**
 * 编辑 SPU
 * 编辑状态, 需要做SPU数据回显
 */
const props = defineProps(['currentSpu'])
onMounted(() => {
  // 获取父组件传递过来的 spu
  const { currentSpu } = props
  // 如果不是编辑，则不做回显
  if (!currentSpu.id) return
  // 数据回显
  Object.assign(spuInfo, currentSpu)
  // 获取spu图片列表
  getSpuImageList(currentSpu.id)
  // 获取销售属性值列表
  getSpuSaleAttrList(currentSpu.id)
})
// 获取spu图片列表
const getSpuImageList = async (spuId: number) => {
  const res = await reqGetSpuImageList(spuId)
  spuInfo.spuImageList = res
  fileList.value = res.map(item => ({
    name: item.imgName,
    url: item.imgUrl
  }))
}
// 获取销售属性值列表
const getSpuSaleAttrList = async (spuId: number) => {
  const res = await reqGetSpuSaleAttrList(spuId)
  spuInfo.spuSaleAttrList = res
}
// 提交更新 SPU
const handleUpdateSpuInfo = async (spuForm: FormInstance) => {
  spuForm.validate(async (valid, fields) => {
    if (valid) { // 验证通过
      await reqUpdateSpuInfo(spuInfo)
      // 更新成功
      ElMessage.success('更新成功')
      // 切换 Tab 至 SpuList 
      emit('changeTab', 1)
    } else {
      ElMessage.error('请按要求填写表单！')
    }
  })

}


// 表单验证
const spuRules = reactive<FormRules>({
  spuName: [{ required: true, message: 'SPU 名称为必填项' }],
  tmId: [{ required: true, message: '品牌为必选项', trigger: 'change' }],
  description: [{ required: true, message: 'SPU 描述为必填项' }],
  spuImageList: [{ type: 'array', required: true, message: '至少上传一张SPU图片', trigger: 'change' }],
  spuSaleAttrList: [{ type: 'array', required: true, message: '销售属性为必填项', trigger: 'change' }]
})
</script>

<style lang="scss" scoped>
[w-full] {
  width: 100%;
  max-width: 100%
}
</style>